/**
 * 通用js方法封装处理
 * Copyright (c) 2019 ruoyi
 */

/**
 * 判断传入参数是否是时间戳，或者日期时间字符串 如 2028-08-08 08:08:08
 * @param {*} time 时间参数
 * @returns {boolean} 是否为有效的时间格式
 */
export function isTimestampOrDateString (time) {
  // 如果参数为空，返回 false
  if (time === undefined || time === null || time === '') {
    return false
  }

  // 如果是数字类型，判断是否为有效时间戳
  if (typeof time === 'number') {
    return isValidTimestamp(time)
  }

  // 如果是字符串类型，判断是否为时间戳字符串或日期时间字符串
  if (typeof time === 'string') {
    const trimmedTime = time.trim()

    // 判断是否为纯数字字符串（时间戳）
    if (/^\d+$/.test(trimmedTime)) {
      return isValidTimestamp(parseInt(trimmedTime))
    }

    // 判断是否为日期时间格式 YYYY-MM-DD HH:mm:ss
    if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(trimmedTime)) {
      return isValidDate(trimmedTime)
    }

    // 判断是否为日期时间格式 YYYY-MM-DD HH:mm
    if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(trimmedTime)) {
      return isValidDate(trimmedTime)
    }

    // 判断是否为日期格式 YYYY-MM-DD
    if (/^\d{4}-\d{2}-\d{2}$/.test(trimmedTime)) {
      return isValidDate(trimmedTime)
    }
  }

  // 如果是 Date 对象
  if (time instanceof Date) {
    return !isNaN(time.getTime())
  }

  return false
}

/**
 * 验证时间戳是否有效
 * @param {number} timestamp 时间戳
 * @returns {boolean} 是否有效
 */
function isValidTimestamp (timestamp) {
  // 检查是否为数字且在合理范围内
  if (typeof timestamp !== 'number' || isNaN(timestamp)) {
    return false
  }

  // 创建日期对象验证时间戳
  const date = new Date(timestamp)
  return !isNaN(date.getTime()) && date.getTime() > 0
}

/**
 * 验证日期字符串是否有效
 * @param {string} dateString 日期字符串
 * @returns {boolean} 是否有效
 */
function isValidDate (dateString) {
  // 替换 - 为 / 以便兼容 Safari 浏览器
  const formattedDate = dateString.replace(/-/g, '/')
  const date = new Date(formattedDate)
  return !isNaN(date.getTime())
}
class Moment {
  static instance = null
  static getInstance () {
    if (!Moment.instance) {
      Moment.instance = new Moment()
    }
    return Moment.instance
  }
  date = null
  constructor() {

  }
  init (data) {
    if (!data) {
      this.date = new Date()
    } else {
      // 判断传入参数是否是时间戳，或者日期时间字符串 如 2028-08-08 08:08
      if (isTimestampOrDateString(data)) {
        this.date = new Date(data)
      } else {
        this.date = new Date();
      }
    }
    return Moment.getInstance()
  }
  offset (key, number) {
    switch (key) {
      case 'year':
        this.date.setFullYear(this.date.getFullYear() + number)
        break;
      case 'month':
        this.date.setMonth(this.date.getMonth() + number)
        break;
      case 'day':
        this.date.setDate(this.date.getDate() + number)
        break;
      case 'week':
        this.offset('day', 7 * number)
        break;
      case 'hour':
        let timeNum = this.date.getTime() + number * 60 * 60 * 1000
        this.date = new Date(timeNum)
        break;
    }
    return Moment.getInstance()
  }
  startOf (type) {
    switch (type) {
      case 'year':
        this.date.setMonth(0);
        this.startOf('month');
        break;
      case 'month':
        this.date.setDate(1)
        this.startOf('day')
        break;
      case 'week':
        // 获取当前周 的周一
        this.offset('day', -this.date.getDay() + 1)
        this.startOf('day')
        break;
      case 'day':
        this.date.setHours(0)
        this.date.setMinutes(0)
        this.date.setSeconds(0)
        break;
    }
    return Moment.getInstance()
  }
  get years () {
    return this.date.getFullYear()
  }
  get months () {
    return this.date.getMonth()
  }
  get days () {
    let a = new Date(this.years,this.months + 1, 0);
    return a.getDate()
  }
  endOf (type) {
    switch (type) {
      case 'year':
        this.date.setMonth(11);
        this.endOf('month');
        break;
      case 'month':
        this.date.setDate(this.days)
        this.endOf('day')
        break;
      case 'week':
        this.offset('day', 7 - this.date.getDay())
        this.endOf('day')
        break;
      case 'day':
        this.date.setHours(23)
        this.date.setMinutes(59)
        this.date.setSeconds(59)
    }
    return Moment.getInstance();
  }
  getTime () {
    return this.date.getTime()
  }
  format (format) {
    return parseTime(this.date, format)
  }

}
export function $moment (date) {
  return Moment.getInstance().init(date)
}
// 日期格式化
export function parseTime (time, pattern) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
      time = parseInt(time)
    } else if (typeof time === 'string') {
      time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '')
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

// 表单重置
export function resetForm (refName) {
  if (this.$refs[refName]) {
    this.$refs[refName].resetFields()
  }
}

// 添加日期范围
export function addDateRange (params, dateRange, propName) {
  let search = params
  search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {}
  dateRange = Array.isArray(dateRange) ? dateRange : []
  if (typeof (propName) === 'undefined') {
    search.params['beginTime'] = dateRange[0]
    search.params['endTime'] = dateRange[1]
  } else {
    search.params['begin' + propName] = dateRange[0]
    search.params['end' + propName] = dateRange[1]
  }
  return search
}

// 添加日期范围
export function addDateRange2 (params, dateRange, propName) {
  let search = params
  search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {}
  dateRange = Array.isArray(dateRange) ? dateRange : []
  if (typeof (propName) === 'undefined') {
    search.params['startTime'] = dateRange[0]
    search.params['endTime'] = dateRange[1]
  } else {
    search.params['begin' + propName] = dateRange[0]
    search.params['end' + propName] = dateRange[1]
  }
  return search
}


// 回显数据字典
export function selectDictLabel (datas, value) {
  if (value === undefined) {
    return ""
  }
  var actions = []
  Object.keys(datas).some((key) => {
    if (datas[key].value == ('' + value)) {
      actions.push(datas[key].label)
      return true
    }
  })
  if (actions.length === 0) {
    actions.push(value)
  }
  return actions.join('')
}

// 回显数据字典（字符串、数组）
export function selectDictLabels (datas, value, separator) {
  if (value === undefined || value.length === 0) {
    return ""
  }
  if (Array.isArray(value)) {
    value = value.join(",")
  }
  var actions = []
  var currentSeparator = undefined === separator ? "," : separator
  var temp = value.split(currentSeparator)
  Object.keys(value.split(currentSeparator)).some((val) => {
    var match = false
    Object.keys(datas).some((key) => {
      if (datas[key].value == ('' + temp[val])) {
        actions.push(datas[key].label + currentSeparator)
        match = true
      }
    })
    if (!match) {
      actions.push(temp[val] + currentSeparator)
    }
  })
  return actions.join('').substring(0, actions.join('').length - 1)
}

// 字符串格式化(%s )
export function sprintf (str) {
  var args = arguments, flag = true, i = 1
  str = str.replace(/%s/g, function () {
    var arg = args[i++]
    if (typeof arg === 'undefined') {
      flag = false
      return ''
    }
    return arg
  })
  return flag ? str : ''
}

// 转换字符串，undefined,null等转化为""
export function parseStrEmpty (str) {
  if (!str || str == "undefined" || str == "null") {
    return ""
  }
  return str
}

// 数据合并
export function mergeRecursive (source, target) {
  for (var p in target) {
    try {
      if (target[p].constructor == Object) {
        source[p] = mergeRecursive(source[p], target[p])
      } else {
        source[p] = target[p]
      }
    } catch (e) {
      source[p] = target[p]
    }
  }
  return source
}

/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 */
export function handleTree (data, id, parentId, children) {
  let config = {
    id: id || 'id',
    parentId: parentId || 'parentId',
    childrenList: children || 'children'
  }

  var childrenListMap = {}
  var tree = []
  for (let d of data) {
    let id = d[config.id]
    childrenListMap[id] = d
    if (!d[config.childrenList]) {
      d[config.childrenList] = []
    }
  }

  for (let d of data) {
    let parentId = d[config.parentId]
    let parentObj = childrenListMap[parentId]
    if (!parentObj) {
      tree.push(d)
    } else {
      parentObj[config.childrenList].push(d)
    }
  }
  return tree
}

/**
* 参数处理
* @param {*} params  参数
*/
export function tansParams (params) {
  let result = ''
  for (const propName of Object.keys(params)) {
    const value = params[propName]
    var part = encodeURIComponent(propName) + "="
    if (value !== null && value !== "" && typeof (value) !== "undefined") {
      if (typeof value === 'object') {
        for (const key of Object.keys(value)) {
          if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
            let params = propName + '[' + key + ']'
            var subPart = encodeURIComponent(params) + "="
            result += subPart + encodeURIComponent(value[key]) + "&"
          }
        }
      } else {
        result += part + encodeURIComponent(value) + "&"
      }
    }
  }
  return result
}

// 返回项目路径
export function getNormalPath (p) {
  if (p.length === 0 || !p || p == 'undefined') {
    return p
  }
  let res = p.replace('//', '/')
  if (res[res.length - 1] === '/') {
    return res.slice(0, res.length - 1)
  }
  return res
}

// 验证是否为blob格式
export function blobValidate (data) {
  return data.type !== 'application/json'
}


//获取当前年月日
// 获取实时时间
export function updateDate () {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, "0");
  const day = String(now.getDate()).padStart(2, "0");
  const hours = String(now.getHours()).padStart(2, "0");
  const minutes = String(now.getMinutes()).padStart(2, "0");
  const seconds = String(now.getSeconds()).padStart(2, "0");
  return `${year}-${month}-${day}`;
}

// 获取实时时间
export function updateTime () {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, "0");
  const day = String(now.getDate()).padStart(2, "0");
  const hours = String(now.getHours()).padStart(2, "0");
  const minutes = String(now.getMinutes()).padStart(2, "0");
  const seconds = String(now.getSeconds()).padStart(2, "0");
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

// 获取实时分钟
export function updateTimeB () {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, "0");
  const day = String(now.getDate()).padStart(2, "0");
  const hours = String(now.getHours()).padStart(2, "0");
  const minutes = String(now.getMinutes()).padStart(2, "0");
  const seconds = String(now.getSeconds()).padStart(2, "0");
  return `${year}-${month}-${day} ${hours}:${minutes}`;
}

/**
 * 工具函数：根据年份和季度，获取季度起止时间（yyyy-mm-dd）
 * @param {number} year - 年份（如2024）
 * @param {number} quarter - 季度（1-4）
 * @returns {object|null} { start: 开始时间, end: 结束时间 }，参数无效时返回null
 */
export const getQuarterDateRange = (year, quarter) => {
  // 参数校验
  if (
    typeof year !== 'number' ||
    year < 1970 ||
    typeof quarter !== 'number' ||
    quarter < 1 ||
    quarter > 4
  ) {
    console.warn('无效参数：年份需≥1970，季度需为1-4的数字');
    return null;
  }

  // 计算起始月份和下季度起始月份
  const startMonth = (quarter - 1) * 3 + 1;
  const nextQuarterStartMonth = quarter * 3 + 1;

  // 计算开始时间
  const startDate = new Date(year, startMonth - 1, 1);
  const start = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, '0')}-${String(startDate.getDate()).padStart(2, '0')}`;

  // 计算结束时间（Date日期为0时指向上个月最后一天）
  const endDate = new Date(year, nextQuarterStartMonth - 1, 0);
  const end = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, '0')}-${String(endDate.getDate()).padStart(2, '0')}`;

  return { start, end };
};

/**
 * 工具函数：获取当前季度及对应的起止时间
 * @returns {object} { quarter: 当前季度（1-4）, start: 开始时间, end: 结束时间 }
 */
export const getCurrentQuarter = () => {
  const now = new Date();
  const currentYear = now.getFullYear();
  const currentMonth = now.getMonth() + 1;
  const currentQuarter = Math.ceil(currentMonth / 3);
  // 复用上面的函数获取起止时间
  const { start, end } = getQuarterDateRange(currentYear, currentQuarter) || {};
  return { quarter: currentQuarter, start, end };
};

// 格式化日期为yyyy-mm-dd格式
export function formatDate (date) {
  const year = date.getFullYear();
  // 月份从0开始，需要加1
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
};


export function debonces (fn, duration) {
  let timer = null;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn(...args);
    }, duration);
  };
}

export function treeToArr (data, id, label, finallevel, children) {
  // 传递配置参数（必传）
  if (JSON.stringify(data) === "{}") {
    return;
  }
  // 第三个参数是递归节点children，如果不穿使默认配置参数中必穿递归的属性是children,
  return data.reduce((res, { id, label, level, finallevel, children }) => {
    res.push({ id, label, level, finallevel });
    if (children && children.length) {
      res = [...res, ...treeToArr(children)]; // 修正了这里的调用
    }
    return res;
  }, []);
}

export function getType (url) {
  if (!url) {
    return;
  }

  // 查找 URL 中最后一个点号之后的部分，即文件扩展名
  const urlParts = url.split("/");
  const fileName = urlParts.pop(); // 获取文件名（可能包含查询参数）
  const fileExtension = fileName.split("?")[0].split(".").pop().toLowerCase(); // 去除查询参数并获取扩展名

  let mimeType = "";
  switch (fileExtension) {
    case "flv":
      mimeType = "flv";
      break;
    case "m3u8":
      mimeType = "m3u8";
      break;
    case "mp4":
      mimeType = "mp4";
      break;
    // default:
    //   mimeType = "flv";
    //   break;
    // 可以在这里添加更多文件类型和对应的 MIME 类型
  }
  return mimeType;
}
